/*
pcm编码器+编码引擎
https://github.com/xiangyuecn/Recorder

编码原理：本编码器输出的pcm格式数据其实就是Recorder中的buffers原始数据（经过了重新采样），16位时为LE小端模式（Little Endian），并未经过任何编码处理

编码的代码和wav.js区别不大，pcm加上一个44字节wav头即成wav文件；所以要播放pcm就很简单了，直接转成wav文件来播放，已提供转换函数 Recorder.pcm2wav
*/
(function () {
  'use strict';

  Recorder.prototype.enc_pcm = {
    stable: true,
    testmsg:
      'pcm为未封装的原始音频数据，pcm数据文件无法直接播放；支持位数8位、16位（填在比特率里面），采样率取值无限制',
  };
  Recorder.prototype.pcm = function (res, True, False) {
    var This = this,
      set = This.set,
      size = res.length,
      bitRate = set.bitRate == 8 ? 8 : 16;

    var buffer = new ArrayBuffer(size * (bitRate / 8));
    var data = new DataView(buffer);
    var offset = 0;

    // 写入采样数据
    if (bitRate == 8) {
      for (var i = 0; i < size; i++, offset++) {
        var val = (res[i] >> 8) + 128;
        data.setInt8(offset, val, true);
      }
    } else {
      for (var i = 0; i < size; i++, offset += 2) {
        data.setInt16(offset, res[i], true);
      }
    }

    True(new Blob([data.buffer], { type: 'audio/pcm' }));
  };

  Recorder.pcm2wav = function (data, True, False) {
    if (data.slice && data.type != null) {
      //Blob 测试用
      data = { blob: data };
    }
    var sampleRate = data.sampleRate || 16000,
      bitRate = data.bitRate || 16;
    if (!data.sampleRate || !data.bitRate) {
      console.warn('pcm2wav必须提供sampleRate和bitRate');
    }
    if (!Recorder.prototype.wav) {
      False('pcm2wav必须先加载wav编码器wav.js');
      return;
    }

    var reader = new FileReader();
    reader.onloadend = function () {
      var pcm;
      if (bitRate == 8) {
        //8位转成16位
        var u8arr = new Uint8Array(reader.result);
        pcm = new Int16Array(u8arr.length);
        for (var j = 0; j < u8arr.length; j++) {
          pcm[j] = (u8arr[j] - 128) << 8;
        }
      } else {
        pcm = new Int16Array(reader.result);
      }

      Recorder({
        type: 'wav',
        sampleRate: sampleRate,
        bitRate: bitRate,
      })
        .mock(pcm, sampleRate)
        .stop(function (wavBlob, duration) {
          True(wavBlob, duration);
        }, False);
    };
    reader.readAsArrayBuffer(data.blob);
  };
})();
